#include <iostream>
#include <string>
#include <vector>
#include <sw/redis++/redis.h>
#include <chrono>
#include <thread>
#include <unordered_set>
#include <unordered_map>

using std::cin;
using std::cout;
using std::endl;
using std::iostream;
using std::string;
using std::vector;

using namespace sw::redis;

template <class T>
void print(T &arr)
{

    for (auto it : arr)
    {
        cout << it << endl;
    }
}
template <class T>
void printoptional(const T &t)
{

    for (auto const &x : t)
    {

        if (x.has_value())
        {
            cout << x.value() << endl;
        }
    }
}

void test_sadd_smembers_scard_spop(Redis &redis)
{

    redis.flushall();

    redis.sadd("key1", {"1", "2", "3"}); // 这里也可以是迭代器区间
    std::unordered_set<string> us;
    auto i = std::inserter(us, us.end()); // 这里需要用它，不能是back_inserter，因为set对应的进行迭代器插入调用的是insert，不是push_back（防止报错）
    redis.smembers("key1", i);
    print(us);
    cout << "个数：" << redis.scard("key1") << endl;

    cout << "spop结果： " << redis.spop("key1").value() << endl;
    cout << "个数：" << redis.scard("key1") << endl;
}

void test_sinter_sunion_sdiff_store(Redis &redis)
{
    redis.flushall();

    redis.sadd("key1", {"1", "2", "3"}); // 这里也可以是迭代器区间
    redis.sadd("key2", {"1", "2", "4"}); // 这里也可以是迭代器区间

    std::unordered_set<string> us;
    auto i = std::inserter(us, us.end()); // 这里需要用它，不能是back_inserter，因为set对应的进行迭代器插入调用的是insert，不是push_back（防止报错）
    redis.sinter({"key1", "key2"}, i);
    cout << "交集： " << endl;
    print(us);
    us.clear();
    i = std::inserter(us, us.end()); // 指向末尾
    redis.sunion({"key1", "key2"}, i);
    cout << "并集： " << endl;
    print(us);

    us.clear();
    i = std::inserter(us, us.end()); // 指向末尾
    redis.sdiff({"key1", "key2"}, i);
    cout << "差集： " << endl;
    print(us);

    redis.sinterstore("des1", {"key1", "key2"});
    redis.sunionstore("des2", {"key1", "key2"});
    redis.sdiffstore("des3", {"key1", "key2"});
}

int main()
{

    Redis redis("tcp://127.0.0.1:6379");
    redis.command("select", 6);
    // test_sadd_smembers_scard_spop(redis);
    test_sinter_sunion_sdiff_store(redis);

    return 0;
}